Imports System.Security.Cryptography
Imports System.IO
Imports System.Text
Namespace Security.Cryptography
    ''' -----------------------------------------------------------------------------
    ''' Project	 : Objectsymmetric
    ''' Class	 : Security.Cryptography.Encryption
    ''' 
    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' Easy to use Encryption class.  
    ''' </summary>
    ''' <remarks>Keeps static public and Private Keys so we can use it anywhere (I.e. is private encryption)
    ''' </remarks>
    ''' <history>
    ''' 	 	3/2/2005	Created
    ''' </history>
    ''' -----------------------------------------------------------------------------
    Public Class Encryption
        Private Const IV_RIJ As String = "tUx/x6X0g0LwvdtzJr0OrA=="
        Private Const KEY_RIJ As String = "z1SKE63TqqzggzvojOr//FEjEWx73hF5XxM7usmSCuM="

        Public Function EncryptURL(ByVal psURL As String) As String
            Dim lsQS As String = psURL.Substring(psURL.IndexOf("?")).Trim
            psURL = psURL.Substring(0, psURL.IndexOf("?"))
            psURL += "?Crypt=" & EncryptString64(lsQS)
            Return psURL
        End Function
        Public Function EncryptString64(ByVal psString As String) As String



            Dim ps As New Symmetric(Symmetric.MyEncryptionType.Rijndael)
            ps.OriginalString = psString
            ps.IVString = IV_RIJ
            ps.KeyString = KEY_RIJ



            Dim lsCrypt As String = ps.Encrypt(psString)
            lsCrypt = lsCrypt.Replace("+", "~^~^")
            lsCrypt = lsCrypt.Replace("/", "||||")
            Return lsCrypt

        End Function
        Public Function DecryptString64(ByVal psString As String) As String
            Dim ps As New Symmetric(Symmetric.MyEncryptionType.Rijndael)
            Dim Server As Web.HttpApplication = New Web.HttpApplication
            psString = Server.Server.UrlDecode(psString)
            ps.IVString = IV_RIJ
            ps.KeyString = KEY_RIJ
            psString = psString.Replace("~^~^", "+")
            psString = psString.Replace("||||", "/")
            ps.EncryptedString = psString
            Dim lsClear As String = ps.Decrypt

            Return lsClear
        End Function

        ''' -----------------------------------------------------------------------------
        ''' <summary>
        ''' Encrypts a string
        ''' </summary>
        ''' <param name="psString">String in plain text</param>
        ''' <returns>Encrypted string</returns>
        ''' <remarks>
        ''' </remarks>
        ''' <history>
        ''' 	 	3/2/2005	Created
        ''' </history>
        ''' -----------------------------------------------------------------------------
        Public Function EncryptString(ByVal psString As String) As String
            Dim ps As New Symmetric(Symmetric.MyEncryptionType.Rijndael)
            ps.OriginalString = psString
            ps.IVString = IV_RIJ
            ps.KeyString = KEY_RIJ
            Return ps.Encrypt(psString)
        End Function
        ''' -----------------------------------------------------------------------------
        ''' <summary>
        ''' Decrypts an encrypted string
        ''' </summary>
        ''' <param name="psString">Encrypted String</param>
        ''' <returns>Plain Text</returns>
        ''' <remarks>Must be encrypted with Encryptstring for this to work
        ''' </remarks>
        ''' <history>
        ''' 	 	3/2/2005	Created
        ''' </history>
        ''' -----------------------------------------------------------------------------
        Public Function DecryptString(ByVal psString As String) As String
            Dim ps As New Symmetric(Symmetric.MyEncryptionType.Rijndael)
            ps.EncryptedString = psString
            ps.IVString = IV_RIJ
            ps.KeyString = KEY_RIJ
            Return ps.Decrypt()
        End Function
        Private Class Symmetric
            '***********************************************
            ' Private Variables
            '***********************************************
            Private mbytEncryptionType As MyEncryptionType
            Private mstrOriginalString As String
            Private mstrEncryptedString As String
            Private mCSP As SymmetricAlgorithm

            '***********************************************
            ' Enumeration for Encryption Type
            ' NOTE: If you change the order of these enums
            ' you will need to also change the NumberToEncryption routine
            '***********************************************
            Public Enum MyEncryptionType As Byte
                DES
                RC2
                Rijndael
                TripleDES
            End Enum

#Region "Public Properties"
            Property EncryptionType() As MyEncryptionType
                Get
                    Return mbytEncryptionType
                End Get
                Set(ByVal Value As MyEncryptionType)
                    If mbytEncryptionType <> Value Then
                        mbytEncryptionType = Value
                        mstrOriginalString = String.Empty
                        mstrEncryptedString = String.Empty

                        Me.SetEncryptor()
                    End If
                End Set
            End Property

            Property CryptoProvider() As SymmetricAlgorithm
                Get
                    Return mCSP
                End Get
                Set(ByVal Value As SymmetricAlgorithm)
                    mCSP = Value
                End Set
            End Property

            Property OriginalString() As String
                Get
                    Return mstrOriginalString
                End Get
                Set(ByVal Value As String)
                    mstrOriginalString = Value
                End Set
            End Property

            Property EncryptedString() As String
                Get
                    Return mstrEncryptedString
                End Get
                Set(ByVal Value As String)
                    mstrEncryptedString = Value
                End Set
            End Property

            Property Key() As Byte()
                Get
                    Return mCSP.Key
                End Get
                Set(ByVal Value As Byte())
                    mCSP.Key = Value
                End Set
            End Property

            Property KeyString() As String
                Get
                    Return Convert.ToBase64String(mCSP.Key)
                End Get
                Set(ByVal Value As String)
                    mCSP.Key = Convert.FromBase64String(Value)
                End Set
            End Property

            Property IV() As Byte()
                Get
                    Return mCSP.IV
                End Get
                Set(ByVal Value As Byte())
                    mCSP.IV = Value
                End Set
            End Property

            Property IVString() As String
                Get
                    Return Convert.ToBase64String(mCSP.IV)
                End Get
                Set(ByVal Value As String)
                    mCSP.IV = Convert.FromBase64String(Value)
                End Set
            End Property
#End Region

#Region "Constructors"
            Public Sub New()
                ' Hard code the default Encryption Type
                mbytEncryptionType = MyEncryptionType.DES

                ' Initialize the Encryptor
                Me.SetEncryptor()
            End Sub

            Public Sub New(ByVal EncryptionType As MyEncryptionType)
                mbytEncryptionType = EncryptionType

                ' Initialize the Encryptor
                Me.SetEncryptor()
            End Sub

            Public Sub New(ByVal EncryptionType As MyEncryptionType, ByVal OriginalString As String)
                mbytEncryptionType = EncryptionType
                mstrOriginalString = OriginalString

                ' Initialize the Encryptor
                Me.SetEncryptor()
            End Sub
#End Region

#Region "Encrypt() Methods"
            Public Function Encrypt() As String
                Dim ct As ICryptoTransform
                Dim ms As MemoryStream
                Dim cs As CryptoStream
                Dim byt() As Byte

                ct = mCSP.CreateEncryptor(mCSP.Key, mCSP.IV)

                byt = Encoding.UTF8.GetBytes(mstrOriginalString)

                ms = New MemoryStream
                cs = New CryptoStream(ms, ct, CryptoStreamMode.Write)
                cs.Write(byt, 0, byt.Length)
                cs.FlushFinalBlock()
                cs.Close()

                mstrEncryptedString = Convert.ToBase64String(ms.ToArray())

                Return mstrEncryptedString
            End Function

            Public Function Encrypt(ByVal OriginalString As String) As String
                mstrOriginalString = OriginalString

                Return Me.Encrypt()
            End Function

            Public Function Encrypt(ByVal OriginalString As String, ByVal EncryptionType As MyEncryptionType) As String
                mstrOriginalString = OriginalString
                mbytEncryptionType = EncryptionType

                Return Me.Encrypt()
            End Function
#End Region

#Region "Decrypt() Methods"
            Public Function Decrypt() As String
                Dim ct As ICryptoTransform
                Dim ms As MemoryStream
                Dim cs As CryptoStream
                Dim byt() As Byte

                ct = mCSP.CreateDecryptor(mCSP.Key, mCSP.IV)

                byt = Convert.FromBase64String(mstrEncryptedString)

                ms = New MemoryStream
                cs = New CryptoStream(ms, ct, CryptoStreamMode.Write)
                cs.Write(byt, 0, byt.Length)
                cs.FlushFinalBlock()

                cs.Close()

                mstrOriginalString = Encoding.UTF8.GetString(ms.ToArray())

                Return mstrOriginalString
            End Function

            Public Function Decrypt(ByVal EncryptedString As String) As String
                mstrEncryptedString = EncryptedString

                Return Me.Decrypt()
            End Function

            Public Function Decrypt(ByVal EncryptedString As String, ByVal EncryptionType As MyEncryptionType) As String
                mstrEncryptedString = EncryptedString
                mbytEncryptionType = EncryptionType

                Return Me.Decrypt()
            End Function
#End Region

#Region "Misc Public Methods"
            Public Function GenerateKey() As String
                mCSP.GenerateKey()

                Return Convert.ToBase64String(mCSP.Key)
            End Function

            Public Function GenerateIV() As String
                mCSP.GenerateIV()

                Return Convert.ToBase64String(mCSP.IV)
            End Function
#End Region

#Region "SetEncryptor Method"
            Private Sub SetEncryptor()
                Select Case mbytEncryptionType
                    Case MyEncryptionType.DES
                        mCSP = New DESCryptoServiceProvider

                    Case MyEncryptionType.RC2
                        mCSP = New RC2CryptoServiceProvider

                    Case MyEncryptionType.Rijndael
                        mCSP = New RijndaelManaged

                    Case MyEncryptionType.TripleDES
                        mCSP = New TripleDESCryptoServiceProvider

                End Select

                ' Generate Key
                mCSP.GenerateKey()

                ' Generate IV
                mCSP.GenerateIV()
            End Sub
#End Region
        End Class

        Private Class Hash
            '***********************************************
            ' Private Variables
            '***********************************************
            Private mbytHashType As MyHashType
            Private mstrOriginalString As String
            Private mstrHashString As String
            Private mhash As HashAlgorithm

            Private mboolUseSalt As Boolean
            Private mstrSaltValue As String = String.Empty
            Private msrtSaltLength As Short = 8


            Public Enum MyHashType As Byte
                MD5
                SHA1
                SHA256
                SHA384
                SHA512
            End Enum

#Region "Public Properties"
            Property HashType() As MyHashType
                Get
                    Return mbytHashType
                End Get
                Set(ByVal Value As MyHashType)
                    If mbytHashType <> Value Then
                        mbytHashType = Value
                        mstrOriginalString = String.Empty
                        mstrHashString = String.Empty

                        Me.SetEncryptor()
                    End If
                End Set
            End Property

            Property SaltValue() As String
                Get
                    Return mstrSaltValue
                End Get
                Set(ByVal Value As String)
                    mstrSaltValue = Value
                End Set
            End Property

            Property SaltLength() As Short
                Get
                    Return msrtSaltLength
                End Get
                Set(ByVal Value As Short)
                    msrtSaltLength = Value
                End Set
            End Property

            Property UseSalt() As Boolean
                Get
                    Return mboolUseSalt
                End Get
                Set(ByVal Value As Boolean)
                    mboolUseSalt = Value
                End Set
            End Property

            Property HashObject() As HashAlgorithm
                Get
                    Return mhash
                End Get
                Set(ByVal Value As HashAlgorithm)
                    mhash = Value
                End Set
            End Property

            Property OriginalString() As String
                Get
                    Return mstrOriginalString
                End Get
                Set(ByVal Value As String)
                    mstrOriginalString = Value
                End Set
            End Property

            Property HashString() As String
                Get
                    Return mstrHashString
                End Get
                Set(ByVal Value As String)
                    mstrHashString = Value
                End Set
            End Property
#End Region

#Region "Constructors"
            Public Sub New()
                ' Set Default Hash Type
                mbytHashType = MyHashType.MD5
            End Sub

            Public Sub New(ByVal HashType As MyHashType)
                mbytHashType = HashType
            End Sub

            Public Sub New(ByVal HashType As MyHashType, _
              ByVal OriginalString As String)
                mbytHashType = HashType
                mstrOriginalString = OriginalString
            End Sub

            Public Sub New(ByVal HashType As MyHashType, _
              ByVal OriginalString As String, _
              ByVal UseSalt As Boolean, _
              ByVal SaltValue As String)
                mbytHashType = HashType
                mstrOriginalString = OriginalString
                mboolUseSalt = UseSalt
                mstrSaltValue = SaltValue
            End Sub
#End Region

#Region "SetEncryptor() Method"
            Private Sub SetEncryptor()
                Select Case mbytHashType
                    Case MyHashType.MD5
                        mhash = New MD5CryptoServiceProvider

                    Case MyHashType.SHA1
                        mhash = New SHA1CryptoServiceProvider

                    Case MyHashType.SHA256
                        mhash = New SHA256Managed

                    Case MyHashType.SHA384
                        mhash = New SHA384Managed

                    Case MyHashType.SHA512
                        mhash = New SHA512Managed

                End Select
            End Sub
#End Region

#Region "CreateHash() Methods"
            Public Function CreateHash() As String
                Dim bytValue() As Byte
                Dim bytHash() As Byte

                ' Create New Crypto Service Provider Object
                SetEncryptor()

                ' Check to see if we will Salt the value
                If mboolUseSalt Then
                    If mstrSaltValue.Length = 0 Then
                        mstrSaltValue = Me.CreateSalt()
                    End If
                End If

                ' Convert the original string to array of Bytes
                bytValue = System.Text.Encoding. _
                  UTF8.GetBytes(mstrSaltValue & mstrOriginalString)

                ' Compute the Hash, returns an array of Bytes
                bytHash = mhash.ComputeHash(bytValue)

                ' Return a base 64 encoded string of the Hash value
                Return Convert.ToBase64String(bytHash)
            End Function

            Public Function CreateHash( _
              ByVal OriginalString As String) As String
                mstrOriginalString = OriginalString

                Return Me.CreateHash()
            End Function

            Public Function CreateHash( _
              ByVal OriginalString As String, _
              ByVal HashType As MyHashType) As String
                mstrOriginalString = OriginalString
                mbytHashType = HashType

                Return Me.CreateHash()
            End Function

            Public Function CreateHash( _
            ByVal OriginalString As String, _
            ByVal UseSalt As Boolean) As String
                mstrOriginalString = OriginalString
                mboolUseSalt = UseSalt

                Return Me.CreateHash()
            End Function

            Public Function CreateHash( _
              ByVal OriginalString As String, _
              ByVal HashType As MyHashType, _
              ByVal UseSalt As Boolean) As String
                mstrOriginalString = OriginalString
                mbytHashType = HashType
                mboolUseSalt = UseSalt

                Return Me.CreateHash()
            End Function

            Public Function CreateHash( _
              ByVal OriginalString As String, _
              ByVal HashType As MyHashType, _
              ByVal SaltValue As String) As String
                mstrOriginalString = OriginalString
                mbytHashType = HashType
                mstrSaltValue = SaltValue

                Return Me.CreateHash()
            End Function

            Public Function CreateHash( _
              ByVal OriginalString As String, _
              ByVal SaltValue As String) As String
                mstrOriginalString = OriginalString
                mstrSaltValue = SaltValue

                Return Me.CreateHash()
            End Function
#End Region

#Region "Misc. Routines"
            Public Sub Reset()
                mstrSaltValue = String.Empty
                mstrOriginalString = String.Empty
                mstrHashString = String.Empty
                mboolUseSalt = False
                mbytHashType = MyHashType.MD5

                mhash = Nothing
            End Sub

            Public Function CreateSalt() As String
                Dim bytSalt(msrtSaltLength) As Byte
                Dim rng As New RNGCryptoServiceProvider

                rng.GetBytes(bytSalt)

                Return Convert.ToBase64String(bytSalt)
            End Function
#End Region
        End Class
    End Class

End Namespace